/**
 * @author denis.onishchenko@gmail.com
 */

package com.prapp.mediag;

import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

final class Post {

    private Long id;
    private String title;
    private String link;
    private Date date;
    private String description;
    private String author;
    private Boolean read;
    private Boolean favorite;
    private Long categoryId;

    public String toString() {
        return "Post{" +
                "id=" + id +
                ", categoryId=" + categoryId +
                '}';
    }

    Long getId() {
        return id;
    }

    void setId(Long id) {
        this.id = id;
    }

    String getTitle() {
        return title;
    }

    void setTitle(String title) {
        this.title = title;
    }

    String getLink() {
        return link;
    }

    void setLink(String link) {
        this.link = link;
    }

    Date getDate() {
        return date;
    }

    void setDate(Date date) {
        this.date = date;
    }

    String getDescription() {
        return description;
    }

    void setDescription(String description) {
        this.description = description;
    }

    String getAuthor() {
        return author;
    }

    void setAuthor(String author) {
        this.author = author;
    }

    Boolean getRead() {
        return read;
    }

    void setRead(Boolean read) {
        this.read = read;
    }

    Boolean getFavorite() {
        return favorite;
    }

    void setFavorite(Boolean favorite) {
        this.favorite = favorite;
    }

    Long getCategoryId() {
        return categoryId;
    }

    void setCategoryId(Long categoryId) {
        this.categoryId = categoryId;
    }

    static final class DBAdapter extends com.feeder.DBAdapter {

        static final String TABLE_NAME = "post";

        static final String COLUMN_ID = "_id";
        static final String COLUMN_TITLE = "title";
        static final String COLUMN_LINK = "link";
        static final String COLUMN_DATE = "date";
        static final String COLUMN_DESCRIPTION = "description";
        static final String COLUMN_AUTHOR = "author";
        static final String COLUMN_IS_READ = "read";
        static final String COLUMN_IS_FAVORITE = "favorite";
        static final String COLUMN_CATEGORY_ID = "category_id";

        static final String[] COLUMNS = {
                COLUMN_ID,
                COLUMN_TITLE,
                COLUMN_LINK,
                COLUMN_DATE,
                COLUMN_DESCRIPTION,
                COLUMN_AUTHOR,
                COLUMN_IS_READ,
                COLUMN_IS_FAVORITE,
                COLUMN_CATEGORY_ID
        };

        static final String[] COLUMNS_ID = {
                COLUMN_ID
        };

        static final String[] COLUMNS_DESCRIPTION = {
                COLUMN_DESCRIPTION
        };

        void createTable(SQLiteDatabase db) {
            String sql = "CREATE TABLE " + TABLE_NAME + " (" +
                    COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE" +
                    ", " + COLUMN_TITLE + " TEXT NOT NULL" +
                    ", " + COLUMN_LINK + " TEXT NOT NULL" +
                    ", " + COLUMN_DATE + " TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP" +
                    ", " + COLUMN_DESCRIPTION + " TEXT" +
                    ", " + COLUMN_AUTHOR + " TEXT" +
                    ", " + COLUMN_IS_READ + " INTEGER NOT NULL DEFAULT 0" +
                    ", " + COLUMN_IS_FAVORITE + " INTEGER NOT NULL DEFAULT 0" +
                    ", " + COLUMN_CATEGORY_ID + " INTEGER NOT NULL" +
                    ", FOREIGN KEY (" + COLUMN_CATEGORY_ID + ") REFERENCES " + Category.DBAdapter.TABLE_NAME + "(" + Category.DBAdapter.COLUMN_ID + ")" +
                    ")";

            db.execSQL(sql);
        }

        protected Post fromCursor(Cursor cursor) {
            Post post = new Post();

            post.setId(getLong(cursor, COLUMN_ID, true));
            post.setTitle(getString(cursor, COLUMN_TITLE, true));
            post.setLink(getString(cursor, COLUMN_LINK, true));
            post.setDate(getDate(cursor, COLUMN_DATE, true));
            post.setDescription(getString(cursor, COLUMN_DESCRIPTION, false));
            post.setAuthor(getString(cursor, COLUMN_AUTHOR, false));
            post.setRead(getBoolean(cursor, COLUMN_IS_READ, true));
            post.setFavorite(getBoolean(cursor, COLUMN_IS_FAVORITE, true));
            post.setCategoryId(getLong(cursor, COLUMN_CATEGORY_ID, true));

            return post;
        }

        protected ContentValues getContentValues(Object item) {
            Post post = (Post) item;

            ContentValues values = new ContentValues(8);

            if (post.getTitle() == null)
                throw new NullPointerException("Title is null");

            values.put(COLUMN_TITLE, post.getTitle());

            if (post.getLink() == null)
                throw new NullPointerException("Link is null");

            values.put(COLUMN_LINK, post.getLink());

            if (post.getDate() != null)
                values.put(COLUMN_DATE, date2Integer(post.getDate()));

            if (post.getDescription() != null)
                values.put(COLUMN_DESCRIPTION, post.getDescription());

            if (post.getAuthor() != null)
                values.put(COLUMN_AUTHOR, post.getAuthor());

            if (post.getRead() != null)
                values.put(COLUMN_IS_READ, boolean2Integer(post.getRead()));

            if (post.getFavorite() != null)
                values.put(COLUMN_IS_FAVORITE, boolean2Integer(post.getFavorite()));

            if (post.getCategoryId() == null)
                throw new NullPointerException("CategoryId is null");

            values.put(COLUMN_CATEGORY_ID, post.getCategoryId());

            return values;
        }

        void insert(Post post, SQLiteDatabase db) {
            long id = insert(post, TABLE_NAME, null, db);
            post.setId(id);
        }

        List queryList(SQLiteDatabase db) {
            String orderBy = COLUMN_DATE + " DESC";

            return queryIds(TABLE_NAME, COLUMNS_ID, null, null, orderBy, COLUMN_ID, db);
        }

        List queryUnreadList(SQLiteDatabase db) {
            String selection = COLUMN_IS_READ + "=?";
            String[] selectionArgs = {String.valueOf(0)};
            String orderBy = COLUMN_DATE + " DESC";

            return queryIds(TABLE_NAME, COLUMNS_ID, selection, selectionArgs, orderBy, COLUMN_ID, db);
        }

        List queryFavoriteList(SQLiteDatabase db) {
            String selection = COLUMN_IS_FAVORITE + "=?";
            String[] selectionArgs = {String.valueOf(1)};
            String orderBy = COLUMN_DATE + " DESC";

            return queryIds(TABLE_NAME, COLUMNS_ID, selection, selectionArgs, orderBy, COLUMN_ID, db);
        }

        List queryUnreadFavoriteList(SQLiteDatabase db) {
            String selection = COLUMN_IS_FAVORITE + "=? AND " + COLUMN_IS_READ + "=?";
            String[] selectionArgs = {String.valueOf(1), String.valueOf(0)};
            String orderBy = COLUMN_DATE + " DESC";

            return queryIds(TABLE_NAME, COLUMNS_ID, selection, selectionArgs, orderBy, COLUMN_ID, db);
        }

        List queryByCategoryList(Category category, SQLiteDatabase db) {
            String selection = COLUMN_CATEGORY_ID + "=?";
            String[] selectionArgs = {String.valueOf(category.getId())};
            String orderBy = COLUMN_DATE + " DESC";

            return queryIds(TABLE_NAME, COLUMNS_ID, selection, selectionArgs, orderBy, COLUMN_ID, db);
        }

        List queryUnreadByCategoryList(Category category, SQLiteDatabase db) {
            String selection = COLUMN_CATEGORY_ID + "=? AND " + COLUMN_IS_READ + "=?";
            String[] selectionArgs = {String.valueOf(category.getId()), String.valueOf(0)};
            String orderBy = COLUMN_DATE + " DESC";

            return queryIds(TABLE_NAME, COLUMNS_ID, selection, selectionArgs, orderBy, COLUMN_ID, db);
        }

        Post queryById(long id, SQLiteDatabase db) {
            String selection = COLUMN_ID + "=?";
            String[] selectionArgs = {String.valueOf(id)};

            return (Post) query(TABLE_NAME, COLUMNS, selection, selectionArgs, db);
        }

        Post queryByLink(Category category, String link, SQLiteDatabase db) {
            String selection = COLUMN_CATEGORY_ID + "=? AND " + COLUMN_LINK + "=?";
            String[] selectionArgs = {String.valueOf(category.getId()), link};

            return (Post) query(TABLE_NAME, COLUMNS, selection, selectionArgs, db);
        }

        String queryDescription(long id, SQLiteDatabase db) {
            String selection = COLUMN_ID + "=?";
            String[] selectionArgs = {String.valueOf(id)};

            return queryString(TABLE_NAME, COLUMNS_DESCRIPTION, selection, selectionArgs, COLUMN_DESCRIPTION, false, db);
        }

        long queryCount(SQLiteDatabase db) {
            String sql = "SELECT COUNT(" + COLUMN_ID + ") COUNT FROM " + TABLE_NAME;
            return queryCount(sql, null, db);
        }

        long queryUnreadCount(SQLiteDatabase db) {
            String sql = "SELECT COUNT(" + COLUMN_ID + ") COUNT FROM " + TABLE_NAME + " WHERE " + COLUMN_IS_READ + "=?";
            String[] selectionArgs = {String.valueOf(0)};
            return queryCount(sql, selectionArgs, db);
        }

        long queryFavoriteCount(SQLiteDatabase db) {
            String sql = "SELECT COUNT(" + COLUMN_ID + ") COUNT FROM " + TABLE_NAME + " WHERE " + COLUMN_IS_FAVORITE + "=?";
            String[] selectionArgs = {String.valueOf(1)};
            return queryCount(sql, selectionArgs, db);
        }

        long queryCountByCategory(long categoryId, SQLiteDatabase db) {
            String sql = "SELECT COUNT(" + COLUMN_ID + ") COUNT FROM " + TABLE_NAME + " WHERE " + COLUMN_CATEGORY_ID + "=?";
            String[] selectionArgs = {String.valueOf(categoryId)};
            return queryCount(sql, selectionArgs, db);
        }

        void updateRead(long id, boolean value, SQLiteDatabase db) {
            updateBoolean(id, value, TABLE_NAME, COLUMN_ID, COLUMN_IS_READ, db);
        }

        void updateFavorite(long id, boolean value, SQLiteDatabase db) {
            updateBoolean(id, value, TABLE_NAME, COLUMN_ID, COLUMN_IS_FAVORITE, db);
        }

        void delete(SQLiteDatabase db) {
            db.delete(TABLE_NAME, null, null);
        }

        void deleteByCategory(Category category, SQLiteDatabase db) {
            String whereClause = COLUMN_CATEGORY_ID + "=?";
            String[] whereArgs = {String.valueOf(category.getId())};

            db.delete(TABLE_NAME, whereClause, whereArgs);
        }

        void deleteByDate(Date date, SQLiteDatabase db) {
            String whereClause = COLUMN_DATE + "<=?";
            String[] whereArgs = {String.valueOf(date2Integer(date))};

            db.delete(TABLE_NAME, whereClause, whereArgs);
        }
    }
}
